package com.token.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.token.converter.SysUserConverter;
import com.token.enums.GenderEnum;
import com.token.mapper.SysPermissionMapper;
import com.token.mapper.SysRoleMapper;
import com.token.mapper.SysUserMapper;
import com.token.mapper.SysUserRoleMapper;
import com.token.model.dto.SysUserDTO;
import com.token.model.po.SysPermission;
import com.token.model.po.SysRole;
import com.token.model.po.SysUser;
import com.token.model.po.SysUserRole;
import com.token.model.vo.SysUserVO;
import com.token.model.vo.TestDictDataUserVO;
import com.token.service.UserService;
import com.token.utils.CodeChangeTextUtils;
import com.token.utils.WebRequestUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @auther: henriy
 * @Date: 2023/10/25
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private SysUserRoleMapper sysUserRoleMapper;

    @Resource
    private SysRoleMapper sysRoleMapper;

    @Resource
    private SysUserConverter sysUserConverter;

    @Resource
    private SysPermissionMapper sysPermissionMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public SysUserVO login(SysUserDTO sysUserDTO, HttpServletRequest request) throws Exception {
        LambdaQueryWrapper<SysUser> userQueryWrapper = Wrappers.lambdaQuery();
        userQueryWrapper.eq(SysUser::getUserName, sysUserDTO.getUserName())
                .eq(SysUser::getPassword, sysUserDTO.getPassword())
                .eq(SysUser::getStatus, 0)
                .eq(SysUser::getDelFlag, 0);

        SysUser sysUser = sysUserMapper.selectOne(userQueryWrapper);
        if (Objects.isNull(sysUser)) {
            throw new Exception("账号密码错误，或用户被冻结");
        }

        StpUtil.login(sysUser.getId());
        SysUserVO sysUserVO = new SysUserVO();
        BeanUtils.copyProperties(sysUser, sysUserVO);

        sysUserVO.setToken(StpUtil.getTokenValue());

        String sexName = CodeChangeTextUtils.codeOfText(GenderEnum.class, String.valueOf(sysUser.getSex()));
        sysUserVO.setSexName(sexName);

        // 获取角色code
        LambdaQueryWrapper<SysUserRole> userRoleQueryWrapper = Wrappers.lambdaQuery();
        userRoleQueryWrapper.eq(SysUserRole::getUserId, sysUser.getId());

        List<Long> roleIdList = sysUserRoleMapper.selectList(userRoleQueryWrapper)
                .stream()
                .map(SysUserRole::getRoleId)
                .collect(Collectors.toList());

        LambdaQueryWrapper<SysRole> roleQueryWrapper = Wrappers.lambdaQuery();
        roleQueryWrapper.in(SysRole::getId, roleIdList);
        List<String> roleCodeList = sysRoleMapper.selectList(roleQueryWrapper)
                .stream()
                .map(SysRole::getRoleCode)
                .collect(Collectors.toList());
        sysUserVO.setRoleCodeList(roleCodeList);

        // 获取权限code
        LambdaQueryWrapper<SysPermission> sysPermissionQueryWrapper = Wrappers.lambdaQuery();
        sysPermissionQueryWrapper.eq(SysPermission::getUserId, sysUser.getId());
        List<String> permCodeList = sysPermissionMapper.selectList(sysPermissionQueryWrapper)
                .stream()
                .map(SysPermission::getPermCode)
                .collect(Collectors.toList());
        sysUserVO.setPermCodeList(permCodeList);

        WebRequestUtils.setLoginUserId(request, sysUser.getId().toString());
        stringRedisTemplate.opsForValue().set("login_user", JSONObject.toJSONString(sysUser));
        return sysUserVO;
    }

    @Override
    public IPage<TestDictDataUserVO> page() {
        LambdaQueryWrapper<SysUser> userQueryWrapper = Wrappers.lambdaQuery();
        userQueryWrapper.eq(SysUser::getStatus, 0).eq(SysUser::getDelFlag, 0);
        IPage<SysUser> pageParam = new Page<>(1, 10);
        IPage<TestDictDataUserVO> pageResult = new Page<>();
        IPage<SysUser> sysUserPage = sysUserMapper.selectPage(pageParam, userQueryWrapper);

        List<SysUser> records = sysUserPage.getRecords();
        List<TestDictDataUserVO> userList = records.stream()
                .map(sysUserConverter::toDictUserVO)
                .collect(Collectors.toList());

        pageResult.setTotal(sysUserPage.getTotal());
        pageResult.setPages(sysUserPage.getPages());
        pageResult.setCurrent(sysUserPage.getCurrent());
        pageResult.setRecords(userList);
        pageResult.setSize(sysUserPage.getSize());
        return pageResult;
    }


}
